package chapter7.homework;

// 多态（Polymorphism）
// 指同一操作作用于不同对象时产生不同行为，主要包括：
// 编译时多态（静态绑定）：通过方法重载实现，编译器根据参数类型决定调用哪个方法
// 运行时多态（动态绑定）：通过继承重写和接口实现，JVM在运行时根据对象实际类型决定调用方法
//
// 运行时多态实现机制
// 继承关系：Dog/Cat/Duck继承Animal父类
// 方法重写：子类重写makeSound()抽象方法
// 向上转型：Animal引用指向子类对象（如Animal animal = new Dog()）
// 动态绑定：JVM通过虚方法表(vtable)在运行时确定实际调用方法

// 1. 继承体系中的运行时多态
abstract class Animal {
    private String name;

    public Animal(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    // 抽象方法强制子类实现
    public abstract void makeSound();

    // 非抽象方法可被子类选择性重写
    public void eat() {
        System.out.println(name + "正在进食");
    }
}

class Dog extends Animal {
    public Dog(String name) {
        super(name);
    }

    @Override
    public void makeSound() {
        System.out.println(getName() + "：汪汪汪！");
    }

    // 新增特有方法
    public void fetch() {
        System.out.println(getName() + "叼回了飞盘");
    }
}

class Cat extends Animal {
    public Cat(String name) {
        super(name);
    }

    @Override
    public void makeSound() {
        System.out.println(getName() + "：喵喵喵~");
    }
}

// 2. 接口实现的多态
interface Swimmable {
    void swim();
}

class Duck extends Animal implements Swimmable {
    public Duck(String name) {
        super(name);
    }

    @Override
    public void makeSound() {
        System.out.println(getName() + "：嘎嘎嘎");
    }

    @Override
    public void swim() {
        System.out.println(getName() + "正在湖面游泳");
    }
}

public class PolymorphismDemo {
    public static void main(String[] args) {
        // 运行时多态示例
        Animal[] animals = {
                new Dog("阿黄"),
                new Cat("小白"),
                new Duck("唐老鸭")
        };

        // 多态调用：同一接口，不同行为
        for (Animal animal : animals) {
            animal.makeSound();  // 动态绑定到具体子类方法[2,4](@ref)
            animal.eat();        // 继承父类默认实现

            // 类型检查与向下转型
            if (animal instanceof Swimmable) {
                ((Swimmable) animal).swim();  // 接口多态调用[6](@ref)
            }
        }

        // 编译时多态示例（方法重载）
        feedAnimal(new Dog("小黑"));
        feedAnimal(new Duck("大黄鸭"));
    }

    // 方法重载实现编译时多态
    public static void feedAnimal(Dog dog) {
        System.out.println("喂食狗粮给" + dog.getName());
    }

    public static void feedAnimal(Duck duck) {
        System.out.println("喂食谷物给" + duck.getName());
    }
}